home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 4 / Example 4.3 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  7.7 KB  |  265 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 4.3: Heightmap Editor                            //
  3. // Written by: C. Granberg, 2005                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "heightMap.h"
  10.  
  11. #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
  12. #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
  13.  
  14. class APPLICATION
  15. {
  16.     public:
  17.         APPLICATION();
  18.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  19.         HRESULT Update(float deltaTime);
  20.         HRESULT Render();
  21.         HRESULT Cleanup();
  22.         HRESULT Quit();
  23.  
  24.     private:
  25.         IDirect3DDevice9* m_pDevice; 
  26.         HEIGHTMAP *m_pHeightMap;
  27.  
  28.         float m_angle, m_angle_b;
  29.         HWND m_mainWindow;
  30.         ID3DXFont *m_pFont;
  31. };
  32.  
  33. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  34. {
  35.     APPLICATION app;
  36.  
  37.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  38.         return 0;
  39.  
  40.     MSG msg;
  41.     memset(&msg, 0, sizeof(MSG));
  42.     int startTime = timeGetTime(); 
  43.  
  44.     while(msg.message != WM_QUIT)
  45.     {
  46.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  47.         {
  48.             ::TranslateMessage(&msg);
  49.             ::DispatchMessage(&msg);
  50.         }
  51.         else
  52.         {    
  53.             int t = timeGetTime();
  54.             float deltaTime = (t - startTime)*0.001f;
  55.  
  56.             app.Update(deltaTime);
  57.             app.Render();
  58.  
  59.             startTime = t;
  60.         }
  61.     }
  62.  
  63.     app.Cleanup();
  64.  
  65.     return msg.wParam;
  66. }
  67.  
  68. APPLICATION::APPLICATION()
  69. {
  70.     m_pDevice = NULL; 
  71.     m_pHeightMap = NULL;
  72.     m_mainWindow = 0;
  73.     m_angle = 0.0f;
  74.     m_angle_b = 0.5f;
  75. }
  76.  
  77. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  78. {
  79.     debug.Print("Application initiated");
  80.  
  81.     //Create Window Class
  82.     WNDCLASS wc;
  83.     memset(&wc, 0, sizeof(WNDCLASS));
  84.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  85.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  86.     wc.hInstance     = hInstance;
  87.     wc.lpszClassName = "D3DWND";
  88.  
  89.     //Register Class and Create new Window
  90.     RegisterClass(&wc);
  91.     m_mainWindow = CreateWindow("D3DWND", "Example 4.3: Heightmap Editor", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  92.     SetCursor(NULL);
  93.     ShowWindow(m_mainWindow, SW_SHOW);
  94.     UpdateWindow(m_mainWindow);
  95.  
  96.     //Create IDirect3D9 Interface
  97.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  98.  
  99.     if(d3d9 == NULL)
  100.     {
  101.         debug.Print("Direct3DCreate9() - FAILED");
  102.         return E_FAIL;
  103.     }
  104.  
  105.     //Check that the Device supports what we need from it
  106.     D3DCAPS9 caps;
  107.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  108.  
  109.     //Hardware Vertex Processing or not?
  110.     int vp = 0;
  111.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  112.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  113.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  114.  
  115.     //Check vertex & pixelshader versions
  116.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  117.     {
  118.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  119.     }
  120.  
  121.     //Set D3DPRESENT_PARAMETERS
  122.     D3DPRESENT_PARAMETERS d3dpp;
  123.     d3dpp.BackBufferWidth            = width;
  124.     d3dpp.BackBufferHeight           = height;
  125.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  126.     d3dpp.BackBufferCount            = 1;
  127.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  128.     d3dpp.MultiSampleQuality         = 0;
  129.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  130.     d3dpp.hDeviceWindow              = m_mainWindow;
  131.     d3dpp.Windowed                   = windowed;
  132.     d3dpp.EnableAutoDepthStencil     = true; 
  133.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  134.     d3dpp.Flags                      = 0;
  135.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  136.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  137.  
  138.     //Create the IDirect3DDevice9
  139.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  140.                                  vp, &d3dpp, &m_pDevice)))
  141.     {
  142.         debug.Print("Failed to create IDirect3DDevice9");
  143.         return E_FAIL;
  144.     }
  145.  
  146.     //Release IDirect3D9 interface
  147.     d3d9->Release();
  148.  
  149.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  150.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  151.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  152.  
  153.     return S_OK;
  154. }
  155.  
  156. HRESULT APPLICATION::Update(float deltaTime)
  157. {
  158.     //Create Heightmap
  159.     if(m_pHeightMap == NULL)
  160.     {
  161.         //Create flat heightmap
  162.         m_pHeightMap = new HEIGHTMAP(m_pDevice, INTPOINT(50,50));
  163.  
  164.         if(FAILED(m_pHeightMap->CreateParticles()))
  165.         {
  166.             debug.Print("Failed to create particles");
  167.             Quit();
  168.         }
  169.     }
  170.     else
  171.     {
  172.         //Control camera
  173.         D3DXMATRIX  matWorld, matView, matProj;        
  174.         D3DXVECTOR2 centre = m_pHeightMap->GetCentre();
  175.         D3DXVECTOR3 Eye    = D3DXVECTOR3(centre.x + cos(m_angle) * cos(m_angle_b) * centre.x * 1.5f,  
  176.                                          sin(m_angle_b) * m_pHeightMap->m_maxHeight * 5.0f, 
  177.                                          -centre.y + sin(m_angle) * cos(m_angle_b) * centre.y * 1.5f);
  178.  
  179.         D3DXVECTOR3 Lookat = D3DXVECTOR3(centre.x, 0.0f,  -centre.y);
  180.  
  181.         D3DXMatrixIdentity(&matWorld);
  182.         D3DXMatrixLookAtLH(&matView, &Eye, &Lookat, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  183.         float fov = 45.0f * (D3DX_PI / 180.0f); 
  184.         D3DXMatrixPerspectiveFovLH( &matProj, fov, 1.3333f, 1.0f, 1000.0f );
  185.  
  186.         m_pDevice->SetTransform(D3DTS_WORLD,      &matWorld);
  187.         m_pDevice->SetTransform(D3DTS_VIEW,       &matView);
  188.         m_pDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  189.  
  190.         //Move selection rectangle
  191.         if(KEYDOWN('A') && m_pHeightMap->m_selRect.left > 0)                            m_pHeightMap->MoveRect(LEFT);
  192.         if(KEYDOWN('D') && m_pHeightMap->m_selRect.right < m_pHeightMap->m_size.x - 1)    m_pHeightMap->MoveRect(RIGHT);
  193.         if(KEYDOWN('W') && m_pHeightMap->m_selRect.top > 0)                                m_pHeightMap->MoveRect(UP);
  194.         if(KEYDOWN('S') && m_pHeightMap->m_selRect.bottom < m_pHeightMap->m_size.y - 1)    m_pHeightMap->MoveRect(DOWN);
  195.  
  196.         //Raise/Lower heightmap
  197.         if(KEYDOWN(VK_ADD))            m_pHeightMap->RaiseTerrain(m_pHeightMap->m_selRect, deltaTime * 3.0f);
  198.         if(KEYDOWN(VK_SUBTRACT))    m_pHeightMap->RaiseTerrain(m_pHeightMap->m_selRect, -deltaTime * 3.0f);
  199.  
  200.         //Smooth Heightmap
  201.         if(KEYDOWN(VK_SPACE))        m_pHeightMap->SmoothTerrain();
  202.     }
  203.  
  204.     if(KEYDOWN(VK_ESCAPE))
  205.         Quit();
  206.  
  207.     //Rotate camera (more on cameras in Chapter 5)
  208.     if(KEYDOWN(VK_UP) && m_angle_b < D3DX_PI * 0.4f)    m_angle_b += deltaTime * 0.5f;
  209.     if(KEYDOWN(VK_DOWN) && m_angle_b > 0.1f)            m_angle_b -= deltaTime * 0.5f;
  210.     if(KEYDOWN(VK_LEFT))                                m_angle -= deltaTime * 0.5f;
  211.     if(KEYDOWN(VK_RIGHT))                                m_angle += deltaTime * 0.5f;
  212.  
  213.     return S_OK;
  214. }    
  215.  
  216. HRESULT APPLICATION::Render()
  217. {
  218.     // Clear the viewport
  219.     m_pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
  220.  
  221.     // Begin the scene 
  222.     if(SUCCEEDED(m_pDevice->BeginScene()))
  223.     {
  224.         if(m_pHeightMap != NULL)m_pHeightMap->Render();
  225.  
  226.         RECT r[] = {{10, 10, 0,0}, {10, 30, 0,0}, {10, 50, 0,0}, {10, 70, 0,0}};
  227.         m_pFont->DrawText(NULL, "Arrows: Move Camera", -1, &r[0], DT_LEFT | DT_TOP | DT_NOCLIP, 0xffffffff);
  228.         m_pFont->DrawText(NULL, "A/W/S/D: Move Square", -1, &r[1], DT_LEFT | DT_TOP | DT_NOCLIP, 0xffffffff);
  229.         m_pFont->DrawText(NULL, "+/-: Raise/Lower Square", -1, &r[2], DT_LEFT | DT_TOP | DT_NOCLIP, 0xffffffff);
  230.         m_pFont->DrawText(NULL, "Space: Smooth Terrain", -1, &r[3], DT_LEFT | DT_TOP | DT_NOCLIP, 0xffffffff);
  231.  
  232.         // End the scene.
  233.         m_pDevice->EndScene();
  234.         m_pDevice->Present(0, 0, 0, 0);
  235.     }
  236.  
  237.     return S_OK;
  238. }
  239.  
  240. HRESULT APPLICATION::Cleanup()
  241. {
  242.     try
  243.     {
  244.         if(m_pHeightMap != NULL)
  245.         {
  246.             delete m_pHeightMap;
  247.             m_pHeightMap = NULL;
  248.         }
  249.  
  250.         m_pFont->Release();
  251.         m_pDevice->Release();
  252.     
  253.         debug.Print("Application terminated");
  254.     }
  255.     catch(...){}
  256.  
  257.     return S_OK;
  258. }
  259.  
  260. HRESULT APPLICATION::Quit()
  261. {
  262.     ::DestroyWindow(m_mainWindow);
  263.     ::PostQuitMessage(0);
  264.     return S_OK;
  265. }